パソコン活用研究ラピュタへの道(アセンブラ、DOS、Windows、旧型PCの活用研究)
DEBUGで機械語
WINDOWS時代になってからパソコンをはじめた方は、あまりDOS窓なんて開くことは無いかもしれません。
ましてや、DEBUG(とは直訳すれば、虫取り)なんて起動したことのある人は、ごく少数でしょう。
いや、DOS時代からパソコン使っていて、しかも自分でプログラムする人でも、DEBUGなんてここ何年も
使ってないのではないでしょうか。おじさんもWindows95を手にして、DOS窓で打ち込むコマンドなんて
dirやcdぐらいなものだったので、ある日、なにげなくDEBUGと打ち込んで、DEBUGが起動した時は
少々びっくりしました。いまだ健在なり、DEBUG。健在なら、せっかくだからちょっと使ってみましょう。
Windows95/98ならアセンブラがなくても、DEBUGを使えば機械語プログラムのごく簡単なものなら
作成できます。とりあえず、DEBUGを使って見ましょう。DOS窓から、DEBUGと打ち込めば、DEBUG
が立ち上がるはずです。
1 DEBUGのコマンド
はじめてDEBUGを見るという人も居ると思うので、代表的なコマンドをあげておきます。
なお、DEBUGでは数値はすべて16進数表記です。後ろにHをつけませんが、16進数なので、ご注意を。
おじさんも、ここでは数値は全て16進数として書きます。
アセンブル | A [アドレス] | アセンブル |
ダンプ | D[アドレス1][アドレス2] | アドレス1からアドレス2までをダンプする |
エンター | E アドレス [リスト] | リストの値をアドレスに入力 |
ゴー | G[=アドレシ1][アドレス2] | アドレス1からアドレス2までを実行 |
ネーム | N ファイル名 | 機械語ファイルの名前をつける |
クイット | Q | DEBUGの終了 |
レジスタ | R [レジスタ名] | レジスタの内容の表示と変更 |
トレース | T[=アドレス][命令数] | 1ステップづつ実行 |
ディスアセンブル | U[アドレス1][アドレス2] | アドレス1からアドレス2までを逆アセンブル |
ライト | W | BXレジスタに0、CXレジシタにプログラムサイズを指定して ディスクにファイルとして書き出す。 |
[ ]で囲んだ項目は省略可
2 実際にDEBUGを使う
プログラム作成例をみるのが、なんにしても一番分かりやすいので、あの有名なHELLOを表示する
機械語プログラムを作成してみます。
C:\WINDOWS>debug -a100 25AB:0100 MOV AH,09 25AB:0102 MOV DX,109 25AB:0105 int 21 25AB:0107 int 20 25AB:0109 -e109 'Hello!$' - -u100,10F 25AB:0100 B409 MOV AH,09 25AB:0102 BA0901 MOV DX,0109 25AB:0105 CD21 INT 21 25AB:0107 CD20 INT 20 25AB:0109 48 DEC AX 25AB:010A 65 DB 65 25AB:010B 6C DB 6C 25AB:010C 6C DB 6C 25AB:010D 6F DB 6F 25AB:010E 2124 AND [SI],SP -g=100 Hello! プログラムは正常に終了しました. -n c:\newgame\hello.com -r cx CX 0000 :10 -w 00010 バイト書き込み中 -q C:\WINDOWS>cd c:\newgame C:\newgame> dir HELLO COM 16 99-07-18 23:52 HELLO.COM C:\newgame>hello Hello! |
DEBUGの起動 オフセットアドレス100番地からアセンブル MS-DOSファンクションコール9番 エンターコマンドで表示データを入力 Uコマンドで逆アセしてみる ここからはデータ Hello!$ なので 正しく逆アセされない。 Gコマンドで実行してみる Nコマンドでパスを含めてファイル名指定 RコマンドでCXにファイルサイズ指定 100番地から10F番地まで16Byte =16進数で 10 Wコマンドでディスクに書き込み dirでちゃんとファイルができたか確認 あった 実行 ちゃんと動作している。プログラム成功 |
というわけでうす。短いものなら、DEBUGで機械語プログラムを作れると思います。
DEBUGで遊んでやって下さい。
3 補足説明
(1) EXE,COMファイルと100番地からの記述(-a100)
実行ファイルに拡張子がEXEのものと、COMのものがあるのは知ってらっしゃると思います。
COMファイルというのは、特殊な(サイズの小さな)実行ファイルで、プログラムが(データ含めて)64Kbyte
以内のものです。細かいことは省きますが、8bitCPU時代風のコーディングに仕上がります。(セグメント
アドレスを全然考えなくてよい)
DEBUGでまさか、64KByte以上の機械語プログラムをつくるという無謀(あるいは、おそれをを知らない
というか、チャレンジ精神に富むというか)な人はいないでしょうから、DEBUGで作成するのは基本的に
COMファイルです。
COMファイルはMS-DOSの約束ごとで、100番地(16進数)からプログラムを開始することになってい
ます。従って、必ず-a100としてコーディングを始めて下さい。
ちなみに、100番地以内は、MS-DOSが使います。
(2) 機械語の簡単な説明
MOV
MOV 第1オペランド, 第2オペランド | 第1オペランドに第2オペランドの内容を転送する |
MOVはmoveの略。まあ、転送令です。
DEBUGでの記述例 (R 汎用レジスタ、 M メモリー)
DEBUGでの記述例 | ||
MOV R, R | MOV AX, CX | AX <-- CX |
MOV M, R | MOV [105], AX | 105番地にAXの内容を転送 |
MOV R, M | MOV BX, [106] | BXに106番地の内容を転送 |
MOV M, 即値 | MOV [110], 5 | 110番地に5を転送。(110番地に5が入る) |
MOV R, 即値 | MOV AL, 5 | ALに5を入れる。 |
DEBUGの場合メモリーは[ ]で囲んで指定します。ただ数値を書くと即値とみなされます。
INT
INT 番号 | 指定番号のソフトウエア割り込み |
ここで使ったINT 21というのは、MS-DOSが用意している各種機能(画面への表示や、キーボードから
の入力など)を呼び出すソフトウエア割り込みです。いわゆるシステムコールというやつです。
ここではシステムコール9番(文字列を画面に出力)を使用しました。
AHレジスタに9(システムコール9番)をセットし、DXレジスタに文字列データのある番地を指定(ここでは
109番地)して INT 21とします。
INT 20はプログラムを終了させる割り込みです。機械語プログラムの終わりはINT
20にしておいて下さい。
さもないと、永遠に終わらない、あるいは暴走するプログラムになってしまいます。
4 後書き
なんの予備知識がなくても、前編の8086の基礎とあわせて見ていただけば、それなりにわかる、を目指して
かなり基礎的なことから、易しく書いてみましたが、いかがでしょうか。
どこまで、基礎にさかのぼって書くかというのはいつも頭を悩ます点です。BitとかByteとかいったことから
始めたら、それこそ、膨大な解説になってしまいます。
はしょるところは、はしょり、本をみてもいまいち理解しにくい点と、本にはない実例を中心にしたいと
いつも心がけております。もっと、ここを解説してくれたら、分かりやすいのにと言う点がありましたら、
メールなり、掲示板でおじさんまでご連絡ください。
けっこうはしょりましたので、アセンブラの本などに立ち返って、網羅的なことは確認して下さい。
また、システムコール使用例等については、いずれ書きたいとおもいますが、「プログラマの隠れ里」に、
よい説明がありますので、参考にして下さい。(!)関連ページの「パソ活研5番街/リンク集]にリンク
してあります。